package org.ucas.faker.web.utils.wx;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import org.ucas.faker.web.dao.patents.SymbolDao;
import org.ucas.faker.web.entity.patents.Agency;
import org.ucas.faker.web.entity.patents.Symbol;
import org.ucas.faker.web.entity.patents.Symbol.Category;
import org.ucas.faker.web.utils.ProvinceNormal;
import org.ucas.faker.web.utils.model.RawPatent;
//import org.ucas.faker.web.entity.patents.PatentOrganization;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class WxParser {

  private JSONObject json;

  private RawPatent patent = new RawPatent();

  private JSONArray arr;

  public WxParser() {
    json = new JSONObject();
  }

  public WxParser(JSONObject json) {
    this.json = json;
  }

  public WxParser json(JSONObject target) {
    this.json = target;
    this.patent = new RawPatent();
    return this;
  }

  public RawPatent parseSearch() {

    parseCommon();

    //parse ipcs
    if (json.containsKey("ipcs")) {
      //List<String> ipcs = new ArrayList<>();
    	patent.ipcs = new ArrayList<>();
      arr = json.getJSONArray("ipcs");
      for (int i = 0; i < arr.size(); ++i) {
    	  Symbol s = new Symbol();
    	  s.setKind(Category.IPC);
    	  s.setPatentId(patent.id);
    	  if(arr.getString(i) != null) s.setOriginal(arr.getString(i));
    	  
    	  patent.ipcs.add(s);
        //ipcs.add();
      }
      //patent.ipcs.add(e)
      //patent.ic = ipcs.stream().collect(Collectors.joining(" | "));
      patent.ipc_count = patent.ipcs.size();
    }

    supply();
    return patent;
  }

  public RawPatent parseDetail() {
    parseCommon();
    parseFamilies();
    parseAssignees();
    
    if (json.containsKey("ipcs")) {
      List<String> ipcs = new ArrayList<>();
      arr = json.getJSONArray("ipcs");
      for (int i = 0; i < arr.size(); ++i) {
        ipcs.add(arr.getJSONObject(i).getString("name"));
      }
      //patent.ic = ipcs.stream().collect(Collectors.joining(" | "));
      patent.ipcs =  ipcs.stream().filter(str->str!=null).map(str-> {
    	  Symbol symbol = new Symbol(Symbol.Category.IPC);
    	  symbol.setOriginal(str);
    	  return symbol;
      }).collect(Collectors.toList());
      patent.ipc_count = ipcs.size();
    }
//    if (json.containsKey("main_ipc")) {
//      patent.icm = json.getJSONObject("main_ipc").getString("ipc");
//    }

    if (json.containsKey("ath"))
      patent.ath = json.getInteger("ath");

    supply();
    return patent;
  }

  public Map<String, List> parseCount(List<String> keys) {
    HashMap<String,List> res = new HashMap<>();
    for(String key:keys) {
      List<String> tmp = new ArrayList<>();
      arr = json.getJSONArray(key);
      if(arr == null) {
        res.put(key,null);
        continue;
      }

      for(int i = 0; i < arr.size(); ++i) {
        tmp.add(arr.getJSONObject(i).getString("name"));
      }
      res.put(key,tmp);
    }
    return res;
  }

  private String language(JSONObject obj) {
    String res = json.getString("zh-cn");
    if (res == null || "".equals(res))
      res = obj.getString("original");
    if (res == null || "".equals(res))
      res = obj.getString("en");

    return res;
  }

  private void parseTitle() {
    if (json.containsKey("title")) {
      patent.ti = language(json.getJSONObject("title"));
    }
  }

  private void parseAbstract() {
    if (json.containsKey("abstract")) {
      patent.ab = language(json.getJSONObject("abstract"));
    }
  }

  private void parseApplicants() {
    if (json.containsKey("applicants")) {
      List<String> applicants = new ArrayList<>();
      List<String> countries = new ArrayList<>();
      arr = json.getJSONArray("applicants");
      for (int i = 0; i < arr.size(); ++i) {
        JSONObject applicant = arr.getJSONObject(i);
        applicants.add(applicant.getJSONObject("name").getString("original"));

        JSONArray countryArr = applicant.getJSONArray("countries");
        if (countryArr != null)
        if (countryArr.size() > 0) {
            String tmp = countryArr.getString(0).toUpperCase();
            if (tmp.length()>=2) {
                countries.add(tmp.charAt(0)+""+tmp.charAt(1));
            }
        }
        
        Agency agency = new Agency();
        if(applicant.getJSONObject("address")!=null)
        	agency.setAddress(applicant.getJSONObject("address").getString("original"));
        if(applicant.getJSONArray("countries").size()>0)
        	agency.setCountry(applicant.getJSONArray("countries").getString(0));
        agency.setKind(Agency.Category.APPLICANT);
        if(applicant.getJSONObject("name")!=null)
        	agency.setName(applicant.getJSONObject("name").getString("original"));
        agency.setWxId(applicant.getString("id"));
        
        patent.applicants.add(agency);
      }
      
      /*
      patent.ap = applicants.stream().collect(Collectors.joining(" | "));
      */
      patent.ap_count = patent.applicants.size();
      /*
      patent.apc = countries.stream().collect(Collectors.joining(" | "));
      */
    }
    //重新保存为PatentOrganization
    /*
    if (json.containsKey("applicants")) {
        List<String> applicants = new ArrayList<>();
        List<String> countries = new ArrayList<>();
        arr = json.getJSONArray("applicants");
        for (int i = 0; i < arr.size(); ++i) {
//            PatentOrganization po = new PatentOrganization();
        	
          JSONObject applicant = arr.getJSONObject(i);
//          po.setName_orginal(applicant.getJSONObject("name").getString("original"));
//          po.setName_orginal_lang(applicant.getJSONObject("name").getString("original_lang"));
//          po.setDocdba(applicant.getJSONObject("name").getString("docdba"));
//          po.setDoc_original(applicant.getJSONObject("name").getString("doc_original"));
//
//          po.setAddress_name(applicant.getJSONObject("address").getString("original"));
//          po.setAddress_orginal_lang(applicant.getJSONObject("address").getString("original_lang"));
//
//          po.setOrg_id(applicant.getString("id"));
//
//          po.setType(applicant.getString("type"));
          

          applicants.add(applicant.getJSONObject("name").getString("original"));

          JSONArray countryArr = applicant.getJSONArray("countries");
          if (countryArr.size() > 0)
            countries.add(countryArr.getString(0));
//          System.out.println(i+"\n"
//            +applicant.getJSONObject("name").getString("original")+"\n"
//            +applicant.getJSONObject("name").getString("original_lang")+"\n"
//            +applicant.getJSONObject("name").getString("docdba")+"\n"
//            +applicant.getJSONObject("name").getString("doc_original")+"\n"
//          );
          
//          po.setCountries(countries.stream().collect(Collectors.joining(" | ")));
          //System.out.println(po.toString());
        }
        
        patent.ap = applicants.stream().collect(Collectors.joining(" | "));
        patent.ap_count = applicants.size();
        patent.apc = countries.stream().collect(Collectors.joining(" | "));
      }
      */
  }

  private void parseInventors() {
    if (json.containsKey("inventors")) {
      List<String> inventors = new ArrayList<>();
      arr = json.getJSONArray("inventors");
      for (int i = 0; i < arr.size(); ++i) {
        JSONObject inventor = arr.getJSONObject(i);
        inventors.add(inventor.getJSONObject("name").getString("original"));
        
        Agency agency = new Agency();
        if(inventor.getJSONObject("address")!=null)
          agency.setAddress(inventor.getJSONObject("address").getString("original"));
        
        if(inventor.containsKey("countries")) {
        	JSONArray countries = inventor.getJSONArray("countries");
            if(countries.size()>0) agency.setCountry(countries.getString(0));
        }

        agency.setKind(Agency.Category.INVENTOR);
        if(inventor.getJSONObject("name")!=null)
          agency.setName(inventor.getJSONObject("name").getString("original"));
        agency.setWxId(inventor.getString("id"));
        
        patent.in.add(agency);
        
      }

      /*
      patent.in = inventors.stream().collect(Collectors.joining(" | "));
      */
      patent.in_count = patent.in.size();
    }
    

    //重新保存为PatentOrganization
    /*
    if (json.containsKey("inventors")) {
        List<String> applicants = new ArrayList<>();
        List<String> countries = new ArrayList<>();
        arr = json.getJSONArray("applicants");
        for (int i = 0; i < arr.size(); ++i) {
//            PatentOrganization po = new PatentOrganization();
        	
          JSONObject applicant = arr.getJSONObject(i);
//          po.setName_orginal(applicant.getJSONObject("name").getString("original"));
//          po.setName_orginal_lang(applicant.getJSONObject("name").getString("original_lang"));
//          po.setDocdba(applicant.getJSONObject("name").getString("docdba"));
//          po.setDoc_original(applicant.getJSONObject("name").getString("doc_original"));
//
//          po.setAddress_name(applicant.getJSONObject("address").getString("original"));
//          po.setAddress_orginal_lang(applicant.getJSONObject("address").getString("original_lang"));
//
//          po.setOrg_id(applicant.getString("id"));
//
//          po.setType(applicant.getString("type"));
          

          applicants.add(applicant.getJSONObject("name").getString("original"));

          JSONArray countryArr = applicant.getJSONArray("countries");
          if (countryArr.size() > 0)
            countries.add(countryArr.getString(0));
//          System.out.println(i+"\n"
//            +applicant.getJSONObject("name").getString("original")+"\n"
//            +applicant.getJSONObject("name").getString("original_lang")+"\n"
//            +applicant.getJSONObject("name").getString("docdba")+"\n"
//            +applicant.getJSONObject("name").getString("doc_original")+"\n"
//          );
          
//          po.setCountries(countries.stream().collect(Collectors.joining(" | ")));
          //System.out.println(po.toString());
        }
    }*/
  }

	private void parsePriorities() {
		patent.prn = new ArrayList<>();
		
		if (json.containsKey("priorities")) {
			// List<String> priorities = new ArrayList<>();
			arr = json.getJSONArray("priorities");
			for (int i = 0; i < arr.size(); ++i) {
				JSONObject priority = arr.getJSONObject(i);
				// priorities.add(priority.getString("priority_number"));
				Symbol s = new Symbol();
				s.setKind(Category.PRN);
				s.setPatentId(patent.id);
				s.setOriginal(priority.getString("priority_number"));
				patent.prn.add(s);
			}

			/*patent.prn =
			 priorities.stream().collect(Collectors.joining(" | "));
			 */
		}

		if (json.containsKey("earliest_priority_date")) {
			patent.prd = json.getString("earliest_priority_date");
		}

	}

	private void parseCpcs() {
		SymbolDao sd;
		patent.cpcs = new ArrayList<>();
		if (json.containsKey("cpcs")) {
			List<String> cpcs = new ArrayList<>();
			arr = json.getJSONArray("cpcs");
			for (int i = 0; i < arr.size(); ++i) {
				JSONObject cpc = arr.getJSONObject(i);
				//System.out.println(cpc.toJSONString());

				Symbol s = new Symbol();
				s.setKind(Category.CPC);
				s.setPatentId(patent.id);
				s.setOriginal(cpc.getString("cpc"));
				patent.cpcs.add(s);
			}

			/*
			 * patent.cpc = cpcs.stream().collect(Collectors.joining(" | "));
			 */
		}

		if (json.containsKey("main_cpc")) {
			patent.ccm = json.getJSONObject("main_cpc").getString("cpc");
		}
	}

  private void parseApplication() {
    patent.an = json.getString("application_number");
    if (json.containsKey("application_date")) {
      patent.ad = json.getString("application_date");
    }
  }

  private void parsePublication() {
    if (json.containsKey("earliest_publication_date"))
      patent.pd = json.getString("earliest_publication_date");
    if (json.containsKey("publication_number")) {
      patent.pn = json.getString("publication_number");
    } else if (json.containsKey("publication_history_map")) {
      arr = json.getJSONArray("publication_history_map");
      if (arr.size() > 0) {
        patent.pn = arr.getJSONObject(0).getString("publication_number");
        patent.pd = arr.getJSONObject(0).getString("publication_date");
      }
    }
  }

  private void parseCitations() {

    if (json.containsKey("citations")) {
      arr = json.getJSONArray("citations");
      List<String> citations = new ArrayList<>();
      for (int i = 0; i < arr.size(); ++i) {
        JSONObject citation = arr.getJSONObject(i);
        citations.add(citation.getString("id"));
      }
      patent.cb_scount = citations.size();
      patent.cb = citations.stream().collect(Collectors.joining(" | "));
    }
  }

  private void parseCited() {
    if (json.containsKey("cited")) {
      arr = json.getJSONArray("cited");
      List<String> citeds = new ArrayList<>();
      for (int i = 0; i < arr.size(); ++i) {
        JSONObject cited = arr.getJSONObject(i);
        citeds.add(cited.getString("id"));
      }
      patent.cf_scount = citeds.size();
      patent.cf = citeds.stream().collect(Collectors.joining(" | "));
    }

    if (json.containsKey("cited_literatures")) {
      arr = json.getJSONArray("cited_literatures");
      List<String> literatures = new ArrayList<>();
      for (int i = 0; i < arr.size(); ++i)
        literatures.add(language(arr.getJSONObject(i)));
      patent.cfl = literatures.stream().collect(Collectors.joining(" | "));
    }

  }

  private void parseAuthorization() {
    if (json.containsKey("authorization_date"))
      patent.gd = json.getString("authorization_date");
  }

  private void parseFamilies() {

  }

  private void parseLicense() {
    if (json.containsKey("licensing")) {
      arr = json.getJSONArray("licensing");
      List<String> licensors = new ArrayList<>();
      List<String> licensees = new ArrayList<>();
      for (int i = 0; i < arr.size(); ++i) {

      }
    }
  }

  private void parseAssignees() {
    if (!json.containsKey("assignees")) return;
    arr = json.getJSONArray("assignees");
    patent.pa = new ArrayList<>();
    
    List<String> assignees = new ArrayList<>();
    List<String> addresses = new ArrayList<>();
    List<String> countries = new ArrayList<>();
    List<String> codes = new ArrayList<>();

    for (int i = 0; i < arr.size(); ++i) {
      JSONObject tmp = arr.getJSONObject(i);
      Agency agency = new Agency();
      if(tmp.getJSONObject("address")!=null)
        agency.setAddress(tmp.getJSONObject("address").getString("original"));
      if(tmp.getJSONArray("countries")!=null&&tmp.getJSONArray("countries").size()>0){
    	  //System.out.println(tmp.getJSONArray("countries"));
    	  agency.setCountry(tmp.getJSONArray("countries").getString(0));
    	  if(agency.getCountry() != null && agency.getCountry().length() > 2)
    	    agency.setCountry(agency.getCountry().substring(0,2).toUpperCase());
      }
      agency.setKind(Agency.Category.ASSIGNEE);
      if(tmp.getJSONObject("name")!=null)
      agency.setName(tmp.getJSONObject("name").getString("original"));
      agency.setWxId(tmp.getString("id"));
      
      //System.out.println(agency.getAddress());
      
      patent.pa.add(agency);
      
      
      
      assignees.add(language(tmp.getJSONObject("name")));
      addresses.add(language(tmp.getJSONObject("address")));

      JSONArray cns = tmp.getJSONArray("countries");
      if (cns.size() > 0) countries.add(cns.getString(0));
      codes.add(tmp.getString("code"));
    }

    //
    /*
    patent.pa = assignees.stream().collect(Collectors.joining(" | "));
    
    patent.pac = countries.stream().collect(Collectors.joining(" | "));
    patent.pacp = codes.stream().collect(Collectors.joining(" | "));
    patent.paad = addresses.stream().collect(Collectors.joining(" | "));
    */
    
    
    
    patent.pa_count = addresses.size();
  }

  private void parseLegalStatus() {

    if(json.containsKey("legal_status_history")) {
      arr = json.getJSONArray("legal_status_history");
      if(arr.size() > 0) {
        JSONObject tmp = arr.getJSONObject(0);
        patent.lhsc = tmp.getString("category");
        patent.lhsp = tmp.getString("description");
        patent.lhsd = tmp.getString("publication_date");
      }
    }

    if (json.containsKey("legal_status")) {
      patent.ls = json.getInteger("legal_status");
    }
    if(json.containsKey("lapse_date")) {
      patent.ld = json.getString("lapse_date");
    }

  }

  private void parseOther() {
    patent.sourceId = json.getString("id");
    if (json.containsKey("type")) {
      patent.pt = json.getString("type");
    }
  }

  private void parseCommon() {
    parseTitle();
    parseAbstract();
    parseApplicants();
    parseApplication();
    parseAuthorization();
    parseCitations();
    parseCited();
    parseCpcs();
    parseInventors();
    parseLegalStatus();
    parsePriorities();
    parsePublication();
    parseOther();
  }

  // 补充对应字段
  private void supply() {
    patent.source = "WX";

    // 填充申请年
    if(patent.ad != null) {
      if(patent.ad.length() == 8) {
    	// Date dt = Date.
        patent.ap_year = Integer.parseInt(patent.ad.substring(0,4));
      } else {
        patent.ad = null;
      }
    }
    
    //填充受理局
    //use apply number 
    if(patent.an != null) {
    	if(patent.an.length()>=2){
    		patent.ro = patent.an.substring(0, 2);
    	}else{
    		patent.ro = null;
    	}
    }
//    System.out.println("public number :: "+patent.pn);
//    System.out.println("apply number :: "+patent.an);
//    System.out.println("receiving office :: "+patent.ro);
    
    patent.icm = new ArrayList<>();
    if(patent.ipcs!=null)
    {
    	for(Symbol symbol:patent.ipcs){
    		Symbol ipc_main = new Symbol();
    		
    		ipc_main.setKind(Symbol.Category.IPC_MAIN);
    		
        	String ipc = symbol.getOriginal();
        	int pos = ipc.indexOf('/');
        	if(pos>0) ipc_main.setOriginal(ipc.substring(0, pos));
        	else ipc_main.setOriginal(ipc);
        	
        	patent.icm.add(ipc_main);
        	//System.out.println("IPC_MAIN    "+ ipc_main.getOriginal());
        }
    }
    
    //填充省份
    if(patent.applicants!=null){
    	for(Agency agent :patent.applicants){
    		String tmp = ProvinceNormal.getInstance().getNormalName(agent.getAddress());
    		if(tmp!=null){
    			patent.apr = tmp;
    			//System.out.println("填充省份"+patent.apr);
    			break;
    		}
    	}
    }
    
    //System.out.println(ipc_main.stream().collect(Collectors.joining(" | ")));
  }


}
